define([
  'jquery',
  'underscore',
  'models/User',
  'views/View',
  'views/media/MediaView',
  'views/media/ModalMediaViewer',
  'views/media/UsersSelection',
  'hbs!template/media/media-viewer'
], function($, _,
            User,
            View, MediaView, ModalMediaViewer, UsersSelection,
            media_template) {
  // MediaViewer
  var MediaViewer = View.extend({
    events: {
      "click button[name=share]": "toggleShare",
      "click div.thumbnail": "openModal"
    },

    views: {
      image: MediaView._views.image,
      video: MediaView._views.video,
      modal: ModalMediaViewer
    },
    
    template: media_template,

    flags: {
          share: true,
          check: false,
          modal: true
          // progess
    },
    
    initialize: function(options) {
      options || (options = {});

      // Call to View's initialize method
      View.prototype.initialize.apply(this, options);

      // Check if are flags. If not default flags
      if(options.flags) {
        this.flags = options.flags;
      }
      
      // Check if are data
      if(options.data) {
        this.data = options.data;
      } else if(options.model) { // From a model
        this.model = options.model;
        this.data = {
          id: this.model.get("id"),
          type: this.model.get("type"),
          source: this.model.get("source"),
          thumbnail: this.model.get("thumbnail")
        };
      } else { // Check if the options object have the type and content url.
          if(options.type && options.content) {
            this.data = {
              id: options.id,
              type: options.type,
              source: options.source,
              thumbnail: options.thumbnail
            };
          }
      }
      
      // Set a different template
      if(options.template) {
        this.template = options.template;
      } 

      // Views for render a image or video
      if(options.views) {
          this.views = options.views;
      }
      
      // Attach to this event. If this view is used in a list, when the list notify it that it was attached to the DOM the renderMedia method will be executed to do some extra work.
      //It's useful for some flash or extra configurations.
      this.bind("list:append", this.renderMedia);

      // Internal initializations
      this._sharing = false; // Flag to know, if renderShare has to be called. 
    },

    render: function() {
      // Render the media viewer base template through View's render function.
      View.prototype.render.apply(this);

      // Render media
      this.renderMedia();
      
      /*// Render parts depending of its flags
      if(this.flags.share) {
        this.renderShare();
      }*/
      
      return this;
    },

    renderMedia: function() {
      // Get the media HTML element where the media view will be put.
      var $media = this.$("div[name=media-viewer]"),
          mediaView;
      
      // Create the correct media view for this data.
      if(this.data.type === 'PHOTO') {
        mediaView = new this.views.image({data: this.data});
      } else if(this.data.type === 'VIDEO') {
        mediaView = new this.views.video({data: this.data});
      }
      $media.html(mediaView.render().el);

      // Function to do some extra work. Sometimes useful using flash.
      mediaView.prepare();
    },

    toggleShare: function() {
      if(this.flags.share) {
        this._sharing = !this._sharing;
        this.render();
        this.renderShare();
      }
    },
    
    renderShare: function() {
      if(this._sharing) {
        var $usersSelection = this.$("#users-selection");
        var usersSelection = new UsersSelection({
          el: $usersSelection
        });

        // Render users selection view
        usersSelection.render();
      }
    },

    openModal: function(/*modal*/) {
      var modal;
      if(this.flags.modal) {
//        this.mediaView.trigger("open:modal");
        if(!modal)
          if(this.views.modal) {
            var options = this.options;
            options.viewer = new MediaViewer(this.options);
            options.viewer.flags.share = false;
            options.viewer.flags.modal = false;
            modal = new this.views.modal(options);
          }
        modal.render();
      }
    },
    
    serialize: function() {
      // Get the data object from View.
      var data = View.prototype.getRenderData.apply(this);
      
      // Put media data in the object for rendering them in the view.
      data.media = this.data;
      // Put the flags into the object for rendering them in the view.
      data._flags = this.flags;

      data._sharing = this._sharing;
      return data;
    }
  });

  
  return MediaViewer;
});